package cn.ito.zjgsu.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.ito.zjgsu.constant.StatusCode;
import cn.ito.zjgsu.domain.Authority;
import cn.ito.zjgsu.domain.AuthorityExample;
import cn.ito.zjgsu.domain.Person;
import cn.ito.zjgsu.domain.PersonExample;
import cn.ito.zjgsu.domain.Role;
import cn.ito.zjgsu.domain.RoleAuthority;
import cn.ito.zjgsu.domain.RoleAuthorityExample;
import cn.ito.zjgsu.domain.RoleExample;
import cn.ito.zjgsu.domain.UserLogin;
import cn.ito.zjgsu.domain.UserLoginExample;
import cn.ito.zjgsu.domain.wrapper.AuthorityWrapper;
import cn.ito.zjgsu.domain.wrapper.PersonWrapper;
import cn.ito.zjgsu.domain.wrapper.RoleWrapper;
import cn.ito.zjgsu.domain.wrapper.UserWrapper;
import cn.ito.zjgsu.mapping.AuthorityMapper;
import cn.ito.zjgsu.mapping.PersonMapper;
import cn.ito.zjgsu.mapping.RoleAuthorityMapper;
import cn.ito.zjgsu.mapping.RoleMapper;
import cn.ito.zjgsu.mapping.UserLoginMapper;
import cn.ito.zjgsu.service.PersonService;
import cn.ito.zjgsu.service.RoleService;
import cn.ito.zjgsu.utils.util.CollectionUtil;

@Service
@Transactional
public class RoleServiceImpl implements RoleService {

	@Resource
	private RoleMapper roleMapper;

	@Resource
	private UserLoginMapper userLoginMapper;

	@Resource
	private PersonMapper personMapper;

	@Resource
	private AuthorityMapper authorityMapper;

	@Resource
	private RoleAuthorityMapper roleAuthorityMapper;
	
	@Resource
	private PersonService personService;
	
	
	
	
	@Override
	public String deleteRole(int rid) {
		String status = StatusCode.FAILURE_STATUS;
		try {
			RoleExample roleExample = new RoleExample();
			roleExample.or().andRoleDeleteTagsEqualTo(Role.ROLE_EXISTS_FLAG).andRoleIdEqualTo(rid);
			Role role = new Role();
			role.setRoleDeleteTags(Role.ROLE_DELETE_FLAG);
			roleMapper.updateByExampleSelective(role, roleExample);
			status = StatusCode.SUCCESS_STATUS;
		} catch (Exception e) {
			status = StatusCode.FAILURE_STATUS;
		}
		return status;
	}
	@Override
	public void deleteRoles(List<Integer> rids) {
		RoleExample roleExample = new RoleExample();
		roleExample.or().andRoleDeleteTagsEqualTo(Role.ROLE_EXISTS_FLAG).andRoleIdIn(rids);
		Role role = new Role();
		role.setRoleDeleteTags(Role.ROLE_DELETE_FLAG);
		roleMapper.updateByExampleSelective(role, roleExample);
	}

	@Override
	public List<Role> queryRoles(int pageNum, int records) {
		// start at 0
		if (pageNum > 0) {
			pageNum--;
		} else {
			pageNum = 0;
		}
		RoleExample roleExample = new RoleExample();
		roleExample.or().andRoleDeleteTagsEqualTo(Role.ROLE_EXISTS_FLAG);
		roleExample.setOffset(pageNum  * records);
		roleExample.setLimit(records);
		List<Role> roles = roleMapper.selectByExample(roleExample);
		return  roles;
	}
	//查询关联了某角色的员工
	public List<Person> queryPersonsLinkedRole(int roleId, int pageNum, int records , String key) {
		List<UserLogin> users = queryUsersObLinkedRole(roleId);
		List<Integer> pids = new ArrayList<Integer>();
		for (UserLogin u : users) {
			pids.add(u.getPersonId());
		}
		pageNum = ((pageNum - 1) >= 0 ? pageNum - 1 : 0) * records;
		if (!CollectionUtil.isSafeEmpty(pids)) {
			return personMapper.selectPersonWithPidsandKeys(pids,key,pageNum,records);
		} else {
			return null;
		}
		

	}

	private List<UserLogin> queryUsersObLinkedRole(int roleId) {
		UserLoginExample userLoginExample = new UserLoginExample();
		userLoginExample.or().andRoleIdEqualTo(roleId).andLoginDeleteTagsEqualTo(UserLogin.USER_EXISTS_FLAG);
		List<UserLogin> users = userLoginMapper.selectByExample(userLoginExample);
		return users;
	}
	public String queryUsersLinkedRole(int roleId ,int pageNum, int records) {
		List<UserLogin> users = queryUsersObLinkedRole(roleId , pageNum ,  records);
		return UserWrapper.toJsonArrayString(UserWrapper.wrapUserLogin(users));
	}
	
	public String queryUsersDislinkedRole(int roleId ,int pageNum, int records,String key) {
		if(pageNum > 0){
			pageNum --;
		}else{
			pageNum = 0;
		}
		List<UserLogin> users = queryUsersObDislinkedRole(roleId, pageNum * records, records);
		return UserWrapper.toJsonArrayString(UserWrapper.wrapUserLogin(users));
	}
	
	
	
	//查看角色未关联账户  某人，一个账号有a角色，一个账号有b角色，查出来已关联未关联里都有他，他应该是已关联的
	public List<UserLogin> queryUsersObDislinkedRole(int roleId, int pageNum, int records) {
		UserLoginExample userLoginExample = new UserLoginExample();
		userLoginExample.or().andRoleIdNotEqualTo(roleId).andLoginDeleteTagsEqualTo(UserLogin.USER_EXISTS_FLAG);
		userLoginExample.or().andRoleIdIsNull().andLoginDeleteTagsEqualTo(UserLogin.USER_EXISTS_FLAG);
		pageNum = formatPageAndExample(pageNum, records, userLoginExample);
		List<UserLogin> users = userLoginMapper.selectByExample(userLoginExample);
		return users;
	}
	//查看角色已关联账户
	public List<UserLogin> queryUsersObLinkedRole(int roleId, int pageNum, int records) {
		UserLoginExample userLoginExample = new UserLoginExample();
		userLoginExample.or().andRoleIdEqualTo(roleId).andLoginDeleteTagsEqualTo(UserLogin.USER_EXISTS_FLAG);
		//pageNum = formatPageNum(pageNum);
		pageNum = formatPageAndExample(pageNum, records, userLoginExample);
		List<UserLogin> users = userLoginMapper.selectByExample(userLoginExample);
		return users;
	}

	public List<PersonWrapper> queryWrappedPersonsLinkedRole(int roleId, int pageNum, int records,String key) {
		List<Person> persons = queryPersonsLinkedRole(roleId, pageNum, records,key);
		if(null == persons){
			return null;
		}else{
			return PersonWrapper.wrapPersonList(persons);
		}
		
	}

	@Override
	public List<PersonWrapper> queryRoleUnrelatedWrappedPerson(int roleId, int pageNum, int records) {
		return PersonWrapper.wrapPersonList(queryRoleUnrelatedPerson(roleId, pageNum, records));
	}

	@Override
	public List<Person> queryRoleUnrelatedPerson(int roleId, int pageNum, int records) {
		List<UserLogin> users = queryUsersObLinkedRole(roleId, pageNum, records);
		List<Integer> pids = new ArrayList<Integer>();
		for (UserLogin u : users) {
			pids.add(u.getPersonId());
		}
		PersonExample personExample = new PersonExample();
		if (!CollectionUtil.isSafeEmpty(pids)) {
			personExample.or().andPersonDeleteTagsEqualTo(Person.PERSON_EXIST_FLAG).andPersonIdNotIn(pids);
		} else {
			personExample.or().andPersonDeleteTagsEqualTo(Person.PERSON_EXIST_FLAG);
		}
		personExample.setLimit(records);
		personExample.setOffset(((pageNum - 1) >= 0 ? pageNum - 1 : 0) * records);

		return personMapper.selectByExample(personExample);
	}

	@Override
	public RoleWrapper queryRoleWrapperByRid(int roleId) {
		RoleExample roleExample = new RoleExample();
		roleExample.or().andRoleIdEqualTo(roleId);
		Role role = roleMapper.selectByExample(roleExample).get(0);
		RoleWrapper roleWrapper = new RoleWrapper(role);
		return roleWrapper;
	}

	@Override
	public String updateRoleWrapper(RoleWrapper rw) {
		String status = StatusCode.FAILURE_STATUS;
		if (validatePermissionsIsSafe(rw)) {
			try {
				updateRoleInfo(rw);
				updateLinks(rw);
				status = StatusCode.SUCCESS_STATUS;
			} catch (Exception e) {
				status = StatusCode.FAILURE_STATUS;
				e.printStackTrace();
			}
		} else {
			status = StatusCode.ERROR_STATUS;
		}
		return status;
	}

	@Override
	public String createRole(RoleWrapper rw) {
		String status = StatusCode.FAILURE_STATUS;
		if (validatePermissionsIsSafe(rw)) {
			try {
				rw.getRole().setRoleId(createRoleInfo(rw));
				createLinks(rw);
				status = StatusCode.SUCCESS_STATUS;
			} catch (Exception e) {
				status = StatusCode.FAILURE_STATUS;
				e.printStackTrace();
			}
		} else {
			status = StatusCode.ERROR_STATUS;
		}
		return status;
	}

	
	
	private void createLinks(RoleWrapper rw) {
		insertLinks(rw);		
	}

	private int formatPageAndExample(int pageNum, int records, UserLoginExample userLoginExample) {
		pageNum = formatPageNum(pageNum);
		userLoginExample.setLimit(records);
		userLoginExample.setOffset(pageNum * records);
		return pageNum;
	}

	private int formatPageNum(int pageNum) {
		if(pageNum > 0){
			pageNum --;
		}else{
			pageNum = 0;
		}
		return pageNum;
	}
	
	//返回插入记录的id
	private int createRoleInfo(RoleWrapper rw) {
		roleMapper.insertSelective(rw.getRole());	
		return (rw.getRole().getRoleId());
	}
	
	private void updateRoleInfo(RoleWrapper rw) {
		RoleExample roleExample = new RoleExample();
		roleExample.or().andRoleIdEqualTo(rw.getRole().getRoleId());
		roleMapper.updateByExampleSelective(rw.getRole(), roleExample);

	}

	private void updateLinks(RoleWrapper roleWrapper) {

		deleteLinks(roleWrapper.getRole().getRoleId());
		insertLinks(roleWrapper);

	}

	private void insertLinks(RoleWrapper roleWrapper) {

		List<Integer> pids = getPidsFromRoleWrapper(roleWrapper);
		List<RoleAuthority> ras = new ArrayList<RoleAuthority>();
		for (int i : pids) {
			RoleAuthority roleAuthority = new RoleAuthority();
			roleAuthority.setRoleId(roleWrapper.getRole().getRoleId());
			roleAuthority.setAuthorityId(i);
			roleAuthority.setRaDeleteTags(RoleAuthority.RA_EXISTS_FLAG);
			ras.add(roleAuthority);
		}
		roleAuthorityMapper.insertList(ras);

	}

	private void deleteLinks(int rid) {
		RoleAuthorityExample roleAuthorityExample = new RoleAuthorityExample();
		roleAuthorityExample.or().andRoleIdEqualTo(rid);
		RoleAuthority ra = new RoleAuthority();
		ra.setRaDeleteTags(false);
		roleAuthorityMapper.updateByExampleSelective(ra, roleAuthorityExample);
	}

	private boolean validatePermissionsIsSafe(RoleWrapper rw) {
		List<Integer> pids = new ArrayList<Integer>();
		for (AuthorityWrapper aw : rw.getPermissions()) {
			pids.add(aw.getAuthority().getAuthorityId());
		}
		AuthorityExample authorityExample = new AuthorityExample();
		List<Authority> authorities = authorityMapper.selectByExample(authorityExample);
		List<Integer> databasePids = new ArrayList<Integer>();
		for (Authority a : authorities) {
			databasePids.add(a.getAuthorityId());
		}
		return (databasePids.containsAll(pids));
	}

	private List<Integer> getPidsFromRoleWrapper(RoleWrapper rw) {
		List<Integer> pids = new ArrayList<Integer>();
		for (AuthorityWrapper aw : rw.getPermissions()) {
			pids.add(aw.getAuthority().getAuthorityId());
		}
		return pids;
	}
	@Override
	public List<Person> queryPersonsDislinkedRole(int roleId, int pageNum, int records, String key) {
		List<Person> linked = new ArrayList<Person>();
		List<Person> all = new ArrayList<Person>();
		
		
		List<UserLogin> users = queryUsersObLinkedRole(roleId);
		List<Integer> pids = new ArrayList<Integer>();
		for (UserLogin u : users) {
			pids.add(u.getPersonId());
		}
		if (!CollectionUtil.isSafeEmpty(pids)) {
			PersonExample personExample = new PersonExample();
			personExample.or().andPersonDeleteTagsEqualTo(Person.PERSON_EXIST_FLAG)
			.andPersonIdIn(pids);
			linked = personMapper.selectByExample(personExample);
		} 
		all = personService.queryAllPerson();
		PersonWrapper.removeAll(all, linked);
		
		
		List<Integer> pids2 = new ArrayList<Integer>();
		for(Person p : all){
			pids2.add(p.getPersonId());
		}
		
		if (!CollectionUtil.isSafeEmpty(pids2)) {
			pageNum = formatPageNum(pageNum);
			return personMapper.selectPersonWithPidsandKeys(pids2,key,pageNum * records,records);
		} else {
			return null;
		}
		
	}
	
	
	

	

}
